const fs = require('fs')
const path = require('path')

module.exports = class HtmlPlugin {
	constructor(options) {
		this.options = Object.assign({
			files: 'pages'
		}, options)
	}

	apply(compiler) {
		// console.log('---------', Object.keys(compiler.hooks))
		compiler.hooks.emit.tapAsync('HtmlWebpackPlugin', (compilation, callback) => {
			let publicPath = compiler.options.output.publicPath
			let outputPath = compiler.options.output.path
			let assets = Object.keys(compilation.assets)
			let resources = getResources(assets, publicPath)
			let pageList = fs.readdirSync(this.options.files)
			let outPath = path.join(outputPath, 'pages')
			let template = this.options.template
			let htmlTemplate = fs.readFileSync(template, 'utf-8')
			mkdirsSync(outPath)
			for (let i = 0; i < pageList.length; i++) {
				let file = pageList[i]
				if (!/\.html$/.test(file))
					continue
				if (template.indexOf(file) > -1)
					continue
				let key = file.replace(/\.html/, '')
				let html = fs.readFileSync(path.join(this.options.files, file), 'utf-8')
				let css = resources.css[key] || ''
				let csscomm = resources.css['common'] || ''
				let manifest = resources.js['manifest'] || ''
				let vendor = resources.js['vendor'] || ''
				let jscomm = resources.js['common'] || ''
				let utils = resources.js['utils'] || ''
				let js = resources.js[key] || ''
				html = htmlTemplate.replace('#block', html)
				html = html.replace(/>[\s\n\t]*</g, '><')
				html = html.replace('</head>', `${css}</head>`)
				html = html.replace('</head>', `${csscomm}</head>`)
				html = html.replace('</body>', `${manifest}</body>`)
				html = html.replace('</body>', `${vendor}</body>`)
				html = html.replace('</body>', `${utils}</body>`)
				html = html.replace('</body>', `${jscomm}</body>`)
				html = html.replace('</body>', `${js}</body>`)
				fs.writeFileSync(path.join(outPath, file), html)
			}
			// console.log('---assets---', assets, resources)
			callback()
		});

	}

}

function getResources(assets, publicPath) {
	assets = assets.filter(val => /(\.js|\.css)$/.test(val))
	let resource = {
		css: {},
		js: {},
	}
	for (let i = 0; i < assets.length; i++) {
		let asset = assets[i]
		let key = asset.replace(/[\s\S]*\//g, '').replace(/\.[\s\S]*/, '')
		if (/\.css$/.test(asset))
			resource.css[key] = `<link href="${publicPath}${asset}" rel="stylesheet">`
		if (/\.js$/.test(asset))
			resource.js[key] = `<script type="text/javascript" src="${publicPath}${asset}"></script>`
	}
	return resource
}

// <script type="text/javascript" src="/dist/assets/js/manifest.a014474a.js">
// </script><script type="text/javascript" src="/dist/assets/js/vendor.5420a8d9c270c13da94b.js">
// </script><script type="text/javascript" src="/dist/assets/js/utils.03f438a5f43505a192de.js"></script>
// 
function mkdirsSync(dirPath) {
	if (!fs.existsSync(dirPath)) {
		let pathTmp = ''
		let dirPathArr = dirPath.split(path.sep)
		for (let i = 0; i < dirPathArr.length; i++) {
			let dirname = dirPathArr[i]
			if (!dirname)
				dirname = path.sep;
			if (pathTmp) {
				pathTmp = path.join(pathTmp, dirname);
			} else {
				pathTmp = dirname;
			}
			if (!fs.existsSync(pathTmp)) {
				fs.mkdirSync(pathTmp)
			}
		}
	}
	return true;
}